package org.jeecg.modules.deepseek.service.impl;

import cn.hutool.core.util.ObjectUtil;
import dev.langchain4j.data.document.Metadata;
import dev.langchain4j.data.embedding.Embedding;
import dev.langchain4j.data.segment.TextSegment;
import dev.langchain4j.model.embedding.EmbeddingModel;
import dev.langchain4j.store.embedding.EmbeddingMatch;
import dev.langchain4j.store.embedding.EmbeddingSearchRequest;
import dev.langchain4j.store.embedding.EmbeddingSearchResult;
import dev.langchain4j.store.embedding.EmbeddingStore;
import dev.langchain4j.store.embedding.filter.Filter;
import dev.langchain4j.store.embedding.inmemory.InMemoryEmbeddingStore;
import org.jeecg.modules.deepseek.pojo.Note;
import org.jeecg.modules.deepseek.service.NoteService;
import org.jeecg.modules.deepseek.tools.WebNoteTools;
import org.jeecg.modules.demo.wuyou.service.ISitemapService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.ai.document.Document;
import org.springframework.ai.vectorstore.VectorStore;
import org.springframework.beans.factory.annotation.Autowired;

import org.springframework.stereotype.Service;

import java.lang.reflect.RecordComponent;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.concurrent.ExecutorService;
import java.util.stream.Collectors;

import static dev.langchain4j.store.embedding.filter.MetadataFilterBuilder.metadataKey;

@Service
public class NoteServiceImpl implements NoteService {

    private static final Logger log = LoggerFactory.getLogger(NoteServiceImpl.class);
    @Autowired
    private EmbeddingStore<TextSegment> inMemoryEmbeddingStore;

    @Autowired
    private EmbeddingModel embeddingModel;
    @Autowired
    private  ExecutorService customThreadPool;

    @Autowired
    ISitemapService sitemapService;

    private static String insertSql = "INSERT INTO sys_note_text_parsing_request (" +
            "note_text, note_title, note_content, note_date, " +
            "note_type,note_type_value, note_source_url, note_key_word, note_mood" +
            ") VALUES (" +
            "#{param.noteText}, #{param.noteTitle}, #{param.noteContent}, #{param.noteDate}, " +
            "#{param.noteType}, #{param.noteTypeValue},#{param.noteSourceUrl}, #{param.noteKeyWord}, #{param.noteMood}" +
            ")";

    //    @Autowired
//    private Neo4jClient neo4jClient;
    // 假设使用一个简单的内存存储，实际应用中可能需要数据库
    private List<Note> notes = new ArrayList<>();

    // 模拟自增ID
    private Long idCounter = 0L;

    @Override
    public void saveNote(WebNoteTools.NoteTextParsingRequest content) {

        // 创建新笔记
// 修改方案一：正确处理类型，不强制转换
        Map<String, Object> metadata = Arrays.stream(content.getClass().getRecordComponents())
                .filter(rc -> !rc.getName().equals("noteContent"))
                .collect(Collectors.toMap(
                        RecordComponent::getName,
                        rc -> {
                            try {
                                Object value = rc.getAccessor().invoke(content);
                                String fieldName = rc.getName();
                                // 这是您要求的新逻辑：
                                if (value instanceof Integer) {
                                    // 如果是 Integer 类型，就直接返回它本身（数字）
                                    return value;
                                } else if ("noteDate".equals(fieldName)) {
                                    // 字符串 -> Date -> 格式化字符串
                                    if (value instanceof String) {
                                        try {
                                            // 解析 ISO 格式字符串
                                            String cleaned = ((String) value).replaceAll("\\s+", " ").trim();
                                            SimpleDateFormat inputFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
                                            Date parsed = inputFormat.parse(cleaned);
                                            return inputFormat.format(parsed);
                                        } catch (Exception e) {
                                            throw new IllegalStateException("noteDate 字段解析失败: " + value, e);
                                        }
                                    } else {
                                        throw new IllegalStateException("noteDate 不是字符串类型: " + value.getClass());
                                    }
                                } else if ("noteType".equals(fieldName)) {
                                    String noteTypeId ="0";
                                    if (value instanceof String) {
                                        String v = (String) value;
                                        String[] levels = v.split("_");
                                        System.out.println("levels = " + Arrays.toString(levels));
                                        Long parentId = 0L;
                                        String sql = "select * from sys_categories where  name = #{param.name} and parent_id = #{param.parent_id};";
                                        String insertSql = "INSERT INTO sys_categories (name, parent_id) VALUES (#{param.name}, #{param.parent_id})";
                                        for (String name : levels) {
                                            HashMap<String, Object> stringLongHashMap = new HashMap<>();
                                            stringLongHashMap.put("name", name);
                                            stringLongHashMap.put("parent_id", parentId);
                                            List<Map<String, Object>> resultList = sitemapService.GetByCondition(sql, stringLongHashMap);
                                            log.info("目前分类：{}", resultList);
                                            if (ObjectUtil.isEmpty(resultList)) {
                                                sitemapService.GetByCondition(insertSql, stringLongHashMap);
                                                log.info("插入新分类：[{}]，父级ID：[{}]", name, parentId);
                                                resultList = sitemapService.GetByCondition(sql, stringLongHashMap);
                                            }
                                            if (!ObjectUtil.isEmpty(resultList)) {
                                                Map<String, Object> map = resultList.get(0);
                                                noteTypeId =map.get("id").toString();
                                                parentId = Long.valueOf(map.get("id").toString()); // 用于下一层分类
                                            } else {
                                                log.warn("插入失败或获取 ID 失败，分类名：{}", name);
                                                break;
                                            }
                                        }
                                    }
                                    return noteTypeId;
                                } else {
                                    return String.valueOf(value);
                                }
                            } catch (Exception e) {
                                // 抛出运行时异常是更好的实践，可以让你知道具体哪个字段出了问题
                                throw new IllegalStateException("Failed to access record component: " + rc.getName(), e);
                            }
                        }

                ));
        TextSegment segment1 = TextSegment.from(content.noteContent(), new Metadata(metadata));
        Embedding embedding1 = embeddingModel.embed(segment1).content();
        inMemoryEmbeddingStore.add(embedding1, segment1);
        metadata.put("noteContent", content.noteContent());
        metadata.put("noteTypeValue", content.noteType());
        sitemapService.GetByCondition(insertSql, metadata);
        customThreadPool.submit(()-> {


        }
        );
    }

    @Override
    public List<Note> getAllNotes() {
        return new ArrayList<>(notes); // 返回副本防止外部修改
    }

    @Override
    public List<EmbeddingMatch<TextSegment>> searchNotes(WebNoteTools.NoteSearchRequest category) {
        Embedding queryEmbedding = embeddingModel.embed(category.noteText()).content();
        EmbeddingSearchRequest embeddingSearchRequest = EmbeddingSearchRequest.builder()
                .queryEmbedding(queryEmbedding)
                .maxResults(10)
                .build();

        EmbeddingSearchResult<TextSegment> relevant = inMemoryEmbeddingStore.search(embeddingSearchRequest);
        List<EmbeddingMatch<TextSegment>> matches = relevant.matches();

        return matches;

    }

    @Override
    public List<String> getAllCategories() {
        return notes.stream()
                .map(Note::getCategory)
                .distinct()
                .collect(Collectors.toList());
    }

    @Override
    public List<Map<String, Object>> testSelect(String content) {
        List<Map<String, Object>> maps = sitemapService.GetByCondition(content, new HashMap<>());
        return maps;
    }

    @Override
    public List<Map<String, Object>> getChildrenCategories(Long parentId) {
        StringBuilder sqlBuilder = new StringBuilder("SELECT id, name, parent_id, sort_order, created_at, updated_at FROM sys_categories WHERE ");
        Map<String, Object> params = new HashMap<>();

        if (parentId == null) {
            // 查询顶级分类（parent_id 为 NULL）
            sqlBuilder.append("parent_id IS NULL");
        } else {
            // 查询指定父分类的子分类
            sqlBuilder.append("parent_id = #{param.parentId}");
            params.put("parentId", parentId);
        }

        // 可以根据需要添加排序，例如按 sort_order 升序
        sqlBuilder.append(" ORDER BY sort_order ASC, id ASC");

        String sqlStr = sqlBuilder.toString();
        System.out.println("Generated SQL: " + sqlStr); // 打印 SQL 方便调试
        System.out.println("Parameters: " + params);   // 打印参数方便调试

        return sitemapService.GetByCondition(sqlStr, params);
    }
}

// 为了完整性，这里是建议的 Note 实体类
